//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:20-5-6
// @Time:上午10:51
//

#include "GeeJoan.h"
#include <stdlib.h>

#define START_SERIALZE_GEEJOAN_PROTOCOL int GEEJOAN_packed_size =0 , GEEJOAN_checkSize = 0 ;void *GEEJOAN_result ;
#define SERIALZE_GEEJOAN_PROTOCOL(T, H)     GEEJOAN_packed_size = H##__get_packed_size(&T);\
                                            GEEJOAN_result = malloc(GEEJOAN_packed_size);\
                                            GEEJOAN_checkSize = H##__pack(&T , GEEJOAN_result);
#define END_SERIALZE_GEEJOAN_PROTOCOL(X) if (GEEJOAN_checkSize == GEEJOAN_packed_size)\
                                            {\
                                                *X = GEEJOAN_result ;\
                                                return GEEJOAN_packed_size;\
                                            } else\
                                            {\
                                                free(GEEJOAN_result);\
                                                return -1;\
                                            }
#define DESERIALZE_GEEJOAN_PROTOCOL(T, H, B, L, O)      T = H##__unpack(NULL , L , B);\
                                                        if (T != NULL)\
                                                        {\
                                                        *O = T ;\
                                                        return ERROR_OK;\
                                                        } else\
                                                        {\
                                                        H##__free_unpacked(T ,NULL);\
                                                        return ERROR_FAIL;\
                                                        }

/******* login start *******/
int serialzeLoginRequest(void **outBuffer, const char *username, const char *password, long long timeStamp)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__LoginRequest loginRequest = GEE_JOAN__PROTOCOL__AUTH__LOGIN_REQUEST__INIT;
    loginRequest.username = username;
    loginRequest.password = password;
    loginRequest.timestamp = timeStamp;
    SERIALZE_GEEJOAN_PROTOCOL(loginRequest, gee_joan__protocol__auth__login_request);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE deserialzeLoginRequest(GeeJoan__Protocol__Auth__LoginRequest **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__LoginRequest *loginRequest;
    DESERIALZE_GEEJOAN_PROTOCOL(loginRequest, gee_joan__protocol__auth__login_request, buffer, bufferLen, out);
}


void free_LoginRequest(GeeJoan__Protocol__Auth__LoginRequest *type)
{
    gee_joan__protocol__auth__login_request__free_unpacked(type, NULL);
    return;
}

int serialzeLoginRespose(void **outBuffer, const char *token)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__LoginRespose loginRespose = GEE_JOAN__PROTOCOL__AUTH__LOGIN_RESPOSE__INIT;
    loginRespose.token = token;
    SERIALZE_GEEJOAN_PROTOCOL(loginRespose, gee_joan__protocol__auth__login_respose);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE deserialzeLoginRespose(GeeJoan__Protocol__Auth__LoginRespose **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__LoginRespose *loginRespose;
    DESERIALZE_GEEJOAN_PROTOCOL(loginRespose, gee_joan__protocol__auth__login_respose, buffer, bufferLen, out);
}

void free_LoginRespose(GeeJoan__Protocol__Auth__LoginRespose *type)
{
    gee_joan__protocol__auth__login_respose__free_unpacked(type, NULL);
    return;
}


/******* login end   *******/


int serialzeRegisterAPI(void **outBuffer, const char *username, const char *password, const char *email)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__RegisterAPI registerApi = GEE_JOAN__PROTOCOL__AUTH__REGISTER_API__INIT;
    registerApi.username = username;
    registerApi.password = password;
    registerApi.email = email;
    SERIALZE_GEEJOAN_PROTOCOL(registerApi, gee_joan__protocol__auth__register_api);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);

}

ERRORCODE deserialzeRegisterAPI(GeeJoan__Protocol__Auth__RegisterAPI **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__RegisterAPI *registerApi;
    DESERIALZE_GEEJOAN_PROTOCOL(registerApi, gee_joan__protocol__auth__register_api, buffer, bufferLen, out);
}


void free_RegisterAPI(GeeJoan__Protocol__Auth__RegisterAPI *type)
{
    gee_joan__protocol__auth__register_api__free_unpacked(type, NULL);
    return;
}


// logout

int serialzeLogoutAPI(void **outBuffer, const char *token, long long currentTime)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__LogoutAPI logoutApi = GEE_JOAN__PROTOCOL__AUTH__LOGOUT_API__INIT;
    logoutApi.token = token;
    logoutApi.timestamp = currentTime;
    SERIALZE_GEEJOAN_PROTOCOL(logoutApi, gee_joan__protocol__auth__logout_api);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE deserialzeLogoutAPI(GeeJoan__Protocol__Auth__LogoutAPI **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__LogoutAPI *logoutApi;
    DESERIALZE_GEEJOAN_PROTOCOL(logoutApi, gee_joan__protocol__auth__logout_api, buffer, bufferLen, out);
}

void free_LogoutAPI(GeeJoan__Protocol__Auth__LogoutAPI *type)
{
    gee_joan__protocol__auth__logout_api__free_unpacked(type, NULL);
    return;
}


/******* ChangePassword start *******/

int serialzeChangePasswordRequest(void **outBuffer, const char *oldToken, const char *newpassword, long long timeStamp)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__ChangePasswordRequest changePasswordRequest = GEE_JOAN__PROTOCOL__AUTH__CHANGE_PASSWORD_REQUEST__INIT;
    changePasswordRequest.newpassword = newpassword;
    changePasswordRequest.oldtoken = oldToken;
    changePasswordRequest.timestamp = timeStamp;
    SERIALZE_GEEJOAN_PROTOCOL(changePasswordRequest, gee_joan__protocol__auth__change_password_request);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE
deserialzeChangePasswordRequest(GeeJoan__Protocol__Auth__ChangePasswordRequest **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__ChangePasswordRequest *request;
    DESERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__auth__change_password_request, buffer, bufferLen, out);

}

void free_ChangePasswordRequest(GeeJoan__Protocol__Auth__ChangePasswordRequest *type)
{
    gee_joan__protocol__auth__change_password_request__free_unpacked(type, NULL);
    return;
}


int serialzeChangePasswordRespose(void **outBuffer, const char *newToken)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__Auth__ChangePasswordRespose request = GEE_JOAN__PROTOCOL__AUTH__CHANGE_PASSWORD_RESPOSE__INIT;
    request.newtoken = newToken;
    SERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__auth__change_password_respose);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE
deserialzeChangePasswordRespose(GeeJoan__Protocol__Auth__ChangePasswordRespose **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__Auth__ChangePasswordRespose *respose;
    DESERIALZE_GEEJOAN_PROTOCOL(respose, gee_joan__protocol__auth__change_password_respose, buffer, bufferLen, out);

}

void free_ChangePasswordRespose(GeeJoan__Protocol__Auth__ChangePasswordRespose *type)
{
    gee_joan__protocol__auth__change_password_respose__free_unpacked(type, NULL);
    return;
}



/******* ChangePassword end   *******/



/******* NetworkPackage start *******/

int serialzeNetWorkPackageRequest(
        void **outBuffer, NetWorkPackageModel mod, int sub_type, long long taskid,
        void *body, int data_len, void *pubilckey, int pubilckey_len)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__NetWork__NetWorkPackageRequest request = GEE_JOAN__PROTOCOL__NET_WORK__NET_WORK_PACKAGE_REQUEST__INIT;
    request.type_m = mod;
    request.type_sub = sub_type;
    request.taskid = taskid;
    request.body.data = body;
    request.body.len = data_len;
    request.pubilckey.data = pubilckey;
    request.pubilckey.len = pubilckey_len;
    SERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__net_work__net_work_package_request);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE
deserialzeNetWorkPackageRequest(NetWorkPackageRequest **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__NetWork__NetWorkPackageRequest *request ;

    DESERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__net_work__net_work_package_request, buffer, bufferLen,
                                out);

}

void free_NetWorkPackageRequest(NetWorkPackageRequest *type)
{
    gee_joan__protocol__net_work__net_work_package_request__free_unpacked(type, NULL);
    return;
}

int serialzeNetWorkPackageRespose(
        void **outBuffer, NetWorkPackageModel mod, int sub_type, long long taskid, int code,
        void *body, int data_len, void *pubilckey, int pubilckey_len)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;

    GeeJoan__Protocol__NetWork__NetWorkPackageRespose respose = GEE_JOAN__PROTOCOL__NET_WORK__NET_WORK_PACKAGE_RESPOSE__INIT;
    respose.type_m = mod;
    respose.taskid = taskid;
    respose.type_sub = sub_type;
    respose.code = code;
    respose.body.data = body;
    respose.body.len = data_len;

    SERIALZE_GEEJOAN_PROTOCOL(respose, gee_joan__protocol__net_work__net_work_package_respose);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE
deserialzeNetWorkPackageRespose(GeeJoan__Protocol__NetWork__NetWorkPackageRespose **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__NetWork__NetWorkPackageRespose *request;
    DESERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__net_work__net_work_package_respose, buffer, bufferLen,
                                out);

}

void free_NetWorkPackageRespose(GeeJoan__Protocol__NetWork__NetWorkPackageRespose *type)
{
    gee_joan__protocol__net_work__net_work_package_respose__free_unpacked(type, NULL);
    return;
}

/******* NetworkPackage end   *******/



/******* IoTMod start *******/
/******* UploadData start *******/


int serialzeUploadSensorDataAPI(
        void **outBuffer,
        const char *token,
        unsigned long long gatewayId,
        unsigned long long deviceId,
        GeeJoan__Protocol__IoT__DataPermissionEnum permission,
        int key,
        const char *data)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;

    GeeJoan__Protocol__IoT__UploadSensorDataAPI api;
    api.token = token;
    api.gatewayid = gatewayId;
    api.deviceid = deviceId;
    api.permission = permission;
    api.key = key;
    api.data = data;
    SERIALZE_GEEJOAN_PROTOCOL(api, gee_joan__protocol__io_t__upload_sensor_data_api);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE deserialzeUploadSensorDataAPI(GeeJoan__Protocol__IoT__UploadSensorDataAPI **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__UploadSensorDataAPI *api;
    DESERIALZE_GEEJOAN_PROTOCOL(api, gee_joan__protocol__io_t__upload_sensor_data_api, buffer, bufferLen, out);
}

void free_UploadSensorDataAPI(GeeJoan__Protocol__IoT__UploadSensorDataAPI *type)
{
    gee_joan__protocol__io_t__upload_sensor_data_api__free_unpacked(type, NULL);
    return;
}
/******* UploadData end   *******/

/******* FindData start *******/
int serialzeFindSensorDataRequest(
        void **outBuffer,
        const char *token,
        unsigned long long gatewayId,
        unsigned long long deviceId,
        int key,
        long long time,
        GeeJoan__Protocol__IoT__FindDirectionEnum direction,
        int size)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__FindSensorDataRequest request;
    request.token = token;
    request.gatewayid = gatewayId;
    request.deviceid = deviceId;
    request.key = key;
    request.time = time;
    request.direction = direction;
    request.size = size;
    SERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__io_t__find_sensor_data_request);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}

ERRORCODE deserialzeFindSensorDataRequest(
        GeeJoan__Protocol__IoT__FindSensorDataRequest **out,
        void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__FindSensorDataRequest *request;
    DESERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__io_t__find_sensor_data_request, buffer, bufferLen, out);
}

void free_FindSensorDataRequest(GeeJoan__Protocol__IoT__FindSensorDataRequest *type)
{
    gee_joan__protocol__io_t__find_sensor_data_request__free_unpacked(type, NULL);
    return;
}

int initSensorDataPackages(SensorDataPackage datas[] , int size)
{
//    if(sizeof(datas)/ sizeof(SensorDataPackage) != size)
//    {
//        return ERROR_FAIL;
//    }
    for (int i = 0; i < size; ++i)
    {
        gee_joan__protocol__io_t__sensor_data_package__init(&datas[i]);
    }
    return ERROR_OK;
}
//int SensorDataPackages_set_Data(SensorDataPackage *datas , int index ,  int key , void * data , int data_len , long long timestamp)
//{
//
//}


int serialzeFindSensorDataRespose(void **outBuffer , unsigned long long GatewayId ,unsigned long long DevideId , SensorDataPackage datas[], int datasize )
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__FindSensorDataRespose respose = GEE_JOAN__PROTOCOL__IO_T__FIND_SENSOR_DATA_RESPOSE__INIT;

    respose.gatewayid = GatewayId;
    respose.deviceid = DevideId;

    SensorDataPackage *temp[datasize];
    for (int i = 0; i < datasize; ++i)
    {
        SensorDataPackage *tempdata = &datas[i];
        temp[i] = tempdata;
    }
    respose.datas = temp;
    respose.n_datas = datasize;
    int testSize = respose.n_datas;


    SERIALZE_GEEJOAN_PROTOCOL(respose , gee_joan__protocol__io_t__find_sensor_data_respose);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeFindSensorDataRespose(FindSensorDataRespose **out , void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__FindSensorDataRespose *respose;
    DESERIALZE_GEEJOAN_PROTOCOL(respose, gee_joan__protocol__io_t__find_sensor_data_respose, buffer, bufferLen, out);

}
void free_FindSensorDataRespose(FindSensorDataRespose *type)
{
    gee_joan__protocol__io_t__find_sensor_data_respose__free_unpacked(type , NULL);
    return;
}
/******* FindData end   *******/

int serialzeControlDeviceRequest(
        void **outBuffer, const char* token,
        unsigned long long GatewayId,
        unsigned long long DevideId,
        const char* data)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__ControlDeviceRequest request = GEE_JOAN__PROTOCOL__IO_T__CONTROL_DEVICE_REQUEST__INIT;

    request.gatewayid =GatewayId;
    request.deviceid = DevideId;
    request.token = token;
    request.data = data;

    SERIALZE_GEEJOAN_PROTOCOL(request , gee_joan__protocol__io_t__control_device_request);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeControlDeviceRequest(ControlDeviceRequest **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__ControlDeviceRequest *request;
    DESERIALZE_GEEJOAN_PROTOCOL(request, gee_joan__protocol__io_t__control_device_request, buffer, bufferLen, out);
}
void free_ControlDeviceRequest(ControlDeviceRequest *type)
{
    gee_joan__protocol__io_t__control_device_request__free_unpacked(type ,NULL);
    return;
}
/******* ControlDeviceRequest end   *******/

/******* ControlDeviceRespose start *******/

int serialzeControlDeviceRespose(void **outBuffer, const char* taskCode,long long time)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__ControlDeviceRespose respose  = GEE_JOAN__PROTOCOL__IO_T__CONTROL_DEVICE_RESPOSE__INIT;
    respose.time = time;
    respose.taskcode = taskCode;
    SERIALZE_GEEJOAN_PROTOCOL(respose , gee_joan__protocol__io_t__control_device_respose);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeControlDeviceRespose(ControlDeviceRespose **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__ControlDeviceRespose *temp;
    DESERIALZE_GEEJOAN_PROTOCOL(temp, gee_joan__protocol__io_t__control_device_respose, buffer, bufferLen, out);
}
void free_ControlDeviceRespose(ControlDeviceRespose *type)
{
    gee_joan__protocol__io_t__control_device_respose__free_unpacked(type ,NULL);
    return;
}
/******* ControlDeviceRespose end   *******/

/******* ControlDeviceListerner start *******/
int serialzeControlDeviceListerner(
        void **outBuffer,
        const char* taskCode,
        const char* data,
        long long time
)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__ControlDeviceListerner listerner  = GEE_JOAN__PROTOCOL__IO_T__CONTROL_DEVICE_LISTERNER__INIT;
    listerner.time = time;
    listerner.data = data;
    listerner.taskcode = taskCode;
    SERIALZE_GEEJOAN_PROTOCOL(listerner , gee_joan__protocol__io_t__control_device_listerner);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeControlDeviceListerner(ControlDeviceListerner **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__ControlDeviceListerner *temp;
    DESERIALZE_GEEJOAN_PROTOCOL(temp, gee_joan__protocol__io_t__control_device_listerner, buffer, bufferLen, out);

}
void free_ControlDeviceListerner(ControlDeviceListerner *type)
{
    gee_joan__protocol__io_t__control_device_listerner__free_unpacked(type ,NULL);
    return;
}
/******* ControlDeviceListerner end   *******/

/******* ControlDeviceListerner start *******/
int serialzeControlDeviceAckAPI(
        void **outBuffer,
        const char* token,
        const char* taskCode,
        int errCode,
        const char* errorMsg
)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__ControlDeviceAckAPI api  = GEE_JOAN__PROTOCOL__IO_T__CONTROL_DEVICE_ACK_API__INIT;
    api.errormsg = errorMsg;
    api.errcode = errCode;
    api.taskcode = taskCode;
    api.token = token;
    SERIALZE_GEEJOAN_PROTOCOL(api , gee_joan__protocol__io_t__control_device_ack_api);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeControlDeviceAckAPI(ControlDeviceAckAPI **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__ControlDeviceAckAPI *temp;
    DESERIALZE_GEEJOAN_PROTOCOL(temp, gee_joan__protocol__io_t__control_device_ack_api, buffer, bufferLen, out);

}
void free_ControlDeviceAckAPI(ControlDeviceAckAPI *type)
{
    gee_joan__protocol__io_t__control_device_ack_api__free_unpacked(type ,NULL);
    return;
}
/******* ControlDeviceListerner end   *******/


/******* ControlDeviceListerner start *******/
int serialzeControlDeviceAckListerner(
        void **outBuffer,
        const char* taskCode,
        int errCode,
        const char* errorMsg,
        long long time
)
{
    START_SERIALZE_GEEJOAN_PROTOCOL;
    GeeJoan__Protocol__IoT__ControlDeviceAckListerner listerner  = GEE_JOAN__PROTOCOL__IO_T__CONTROL_DEVICE_ACK_LISTERNER__INIT;
    listerner.errormsg = errorMsg;
    listerner.errcode = errCode;
    listerner.taskcode = taskCode;
    listerner.time = time;
    SERIALZE_GEEJOAN_PROTOCOL(listerner , gee_joan__protocol__io_t__control_device_ack_listerner);
    END_SERIALZE_GEEJOAN_PROTOCOL(outBuffer);
}
ERRORCODE deserialzeControlDeviceAckListerner(ControlDeviceAckListerner **out, void *buffer, int bufferLen)
{
    GeeJoan__Protocol__IoT__ControlDeviceAckListerner *temp;
    DESERIALZE_GEEJOAN_PROTOCOL(temp, gee_joan__protocol__io_t__control_device_ack_listerner, buffer, bufferLen, out);

}
void free_ControlDeviceAckListerner(ControlDeviceAckListerner *type)
{
    gee_joan__protocol__io_t__control_device_ack_listerner__free_unpacked(type ,NULL);
    return;
}
/******* ControlDeviceListerner end   *******/




/******* IoTMod end   *******/



/******* Tool start   *******/


static int hexCharToInt(char c)
{
    if (c >= '0' && c <= '9') return (c - '0');
    if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
    if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
    return 0;
}

int HexString2Char(void **outData ,  const char*data , int len  )
{
    char *result ;
    int resultLen = len /2 ;
    if(len == 0 )
    {
        return -1;
    }
    result = (char*)malloc(resultLen);
    for (int i = 0; i < resultLen; ++i)
    {
        result[i] = (char)((hexCharToInt(data[i*2]) << 4) | hexCharToInt(data[i*2+1]));
    }
    *outData = result;

    return resultLen;
}
/******* Tool end   *******/

